package com.yuncheng.spcyApi.flowService;

import com.yuncheng.entity.YcSysUser;
import com.yuncheng.vo.CurrentUserVo;
import org.apache.commons.collections.CollectionUtils;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.yuncheng.spcyApi.busService.BusService;
import com.yuncheng.spcyApi.constant.common.LogConstant;
import com.yuncheng.spcyApi.constant.flow.YbjcyFlowConstant;
import com.yuncheng.spcyApi.constant.common.SpcyConstant;
import com.yuncheng.spcyApi.entity.*;
import com.yuncheng.spcyApi.mapper.SpcyRsHcyMapper;
import com.yuncheng.spcyApi.service.*;
import com.yuncheng.spcyApi.service.impl.YcSysUserServiceImpl;
import com.yuncheng.spcyApi.utils.DateConvert;
import com.yuncheng.spcyApi.utils.GetCurrentUserUtils;
import com.yuncheng.spcyApi.utils.GetUuIdUtils;

import com.yuncheng.spcyApi.vo.common.Result;
import com.yuncheng.spcyApi.vo.flow.AgentVo;
import com.yuncheng.spcyApi.vo.flow.YbjcyFlowMapVo;
import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.beanutils.ConvertUtils;
import org.apache.commons.lang3.StringUtils;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Component;
import utils.DateConversionUtils;
import utils.LogUtils;
import utils.ObjectToMapUtils;

import javax.annotation.Resource;
import java.lang.reflect.InvocationTargetException;
import java.util.*;
import java.util.stream.Collectors;

@Component(value = "ybjcyFlowService")
public class YbjcyFlowService extends FlowService{
    private static final Logger log = LoggerFactory.getLogger(YbjcyFlowService.class);

    @Resource
    @Lazy
    private YbjcyFlowConstant flowConstant;

    @Resource
    @Lazy
    private ISpcySqsxJobService spcySqsxJobService;

    @Resource
    @Lazy
    private ISpcyKpYbjcyService spcyKpYbjcyService;

    @Resource
    @Lazy
    private ISpcySqsxBaiscService spcySqsxBaiscService;

    @Resource
    @Lazy
    private ISysUserFgldService sysUserFgldService;

    @Resource
    @Lazy
    private SpcyRsHcyMapper spcyRsHcyMapper;

    @Resource
    @Lazy
    private YcSysUserServiceImpl ycSysUserService;

    @Resource
    @Lazy
    private IYcSysOrgService ycSysOrgService;

    @Resource
    @Lazy
    private BusService busService;

    @Resource
    @Lazy
    private ISpcyLogService spcyLogService;

    /**
     * 添加预备检查员 - 初始化流程
     * @param sqsxid
     */
    public void joinYbJcyJob(String sqsxid){
        CurrentUserVo currentUser = GetCurrentUserUtils.getCurrentUser();
        if (currentUser == null){
            log.error("登录失效，请重新登录");
            return;
        }
        SpcySqsxBasic sqsx = spcySqsxBaiscService.getById(sqsxid);
        if (sqsx == null){
            log.error("申请事项【{}】为空",sqsxid);
            return;
        }

        List<SpcySqsxXpjl> tyXpXpjlList = busService.getTyXpXpjlList(sqsxid, SpcyConstant.FLOW_TYPE_CY);
        if (CollectionUtils.isEmpty(tyXpXpjlList)){
            return;
        }
        List<SpcySqsxXpjl> ybList = tyXpXpjlList.stream().filter(x -> StringUtils.isNotBlank(x.getFssk())
                    && x.getFssk().contains(SpcyConstant.HCY_SSK_YB)).collect(Collectors.toList());

        List<SpcySqsxXpjl> zzList = tyXpXpjlList.stream().filter(x -> StringUtils.isNotBlank(x.getFssk())
                    && x.getFssk().contains(SpcyConstant.HCY_SSK_ZZ)).collect(Collectors.toList());

        String zzids = "";
        String zzmcs = "";
        // 拿到选派的组长
        if (CollectionUtils.isNotEmpty(zzList)){
            for (SpcySqsxXpjl xpjl : zzList){
                if (StringUtils.isNotBlank(zzids)){
                    zzids += ","+xpjl.getFuserid();
                }else {
                    zzids += xpjl.getFuserid();
                }

                //
                if (StringUtils.isNotBlank(zzmcs)){
                    zzmcs += ","+xpjl.getFjcyxm();
                }else {
                    zzmcs += xpjl.getFjcyxm();
                }
            }
        }

        // 初始化记录
        if (CollectionUtils.isNotEmpty(ybList)){
                for (SpcySqsxXpjl xpjl : ybList) {
                    String ybid = GetUuIdUtils.ReplaceUuId();
                    SpcyKpYbjcy ybjcy = new SpcyKpYbjcy();
                    ybjcy.setId(ybid);
                    ybjcy.setFjcyid(xpjl.getFjcyid());
                    ybjcy.setFuserid(xpjl.getFuserid());
                    ybjcy.setFjcyxm(xpjl.getFjcyxm());
                    ybjcy.setFsqsxid(sqsxid);
                    ybjcy.setFzzid(zzids);
                    ybjcy.setFzzxm(zzmcs);
                    ybjcy.setFgzdw(xpjl.getFgzdw());
                    ybjcy.setFkssj(new Date());
                    ybjcy.setFcyjcfw(sqsx.getFcyjcfw());

                    String jcsj = "";
                    if (sqsx.getFcykssj() != null && sqsx.getFcyjssj() != null) {
                        jcsj = DateConversionUtils.DateToStringYYYYMMDD(sqsx.getFcykssj()) + "至" + DateConversionUtils.DateToStringYYYYMMDD(sqsx.getFcyjssj());
                    }
                    ybjcy.setFjcsj(jcsj);
                    ybjcy.setFqymc(sqsx.getFqymc());
                    ybjcy.setFjclx(sqsx.getFjclx());
                    StringBuffer jcyzj = new StringBuffer();
                    jcyzj.append("<p>&nbsp;一、检查基本情况</p>\n" +
                            "<p>（包括对被检查对象（品种）的基本了解）</p>\n" +
                            "<p>二、承担的检查任务</p>\n" +
                            "<p>（简述承担的检查任务）</p>\n" +
                            "<p>三、完成的情况</p>\n" +
                            "<p>（结合承担的检查任务，简述检查的思路和检查关注 的重点）</p>\n" +
                            "<p>四、体会与收获</p>\n" +
                            "<p>（对检查的深入了解，对企业质量管理方面。</p>\n" +
                            "<p>五、认知和思考</p>\n" +
                            "<p>（对检查存在问题的思考、对团队合作以及检查思路 的体会与收获等）。</p>\n" +
                            "<p>六、意见与建议</p>\n" +
                            "<p>（对检查的组织、检查方案、检查的形式等方面均可 提出意见与建议）</p>");
                    ybjcy.setFsxjcyzj(jcyzj.toString());

                    // 存在流程-删除
                    List<SpcyKpYbjcy> isExistList = spcyKpYbjcyService.list(new LambdaQueryWrapper<SpcyKpYbjcy>()
                            .eq(SpcyKpYbjcy::getFsqsxid, sqsxid));
                    if (CollectionUtils.isNotEmpty(isExistList)){
                        for (SpcyKpYbjcy ybjcy1 : isExistList){
                            spcyKpYbjcyService.removeById(ybjcy1.getId());
                            spcySqsxJobService.remove(new LambdaQueryWrapper<SpcySqsxJob>().eq(SpcySqsxJob::getFpid,ybjcy1.getId()));
                        }
                    }
                    spcyKpYbjcyService.save(ybjcy);

                    this.initJob(ybid,currentUser); // 初始化-预备检查员流程
                }
        }

    }

    /**
     * 流程处理
     * */
    public Result handleFlow(YbjcyFlowMapVo ybjcyFlowVo, SpcySqsxJob nowJob, String jobId, String ybid, String submitType, String opinion){
        // 当前流程任务
        if (StringUtils.isNotBlank(jobId)) {
            nowJob = spcySqsxJobService.getById(jobId);
        }

        if (nowJob == null){
            return Result.error("当前流程任务不存在，请重试");
        }

        // 提交按钮
        if (submitType.equals(YbjcyFlowConstant.SUBMIT_TYPE_SUBMIT)) {
            if (nowJob == null) {
                return Result.error("当前流程任务不存在");
            }
        }

        // 个人总结
        if (submitType.equals(YbjcyFlowConstant.SUBMIT_TYPE_SUBMIT) && nowJob.getFhjmc().equals(YbjcyFlowConstant.HJMC_DJ)){
            SpcyKpYbjcy ybjcy = spcyKpYbjcyService.getById(ybid);
            if (ybjcy == null){
                return Result.error("当前预备检查员考评记录不存在，请联系管理员");
            }
            if (StringUtils.isBlank(ybjcy.getFzzid())){
                ybjcyFlowVo.setNextNode(YbjcyFlowConstant.HJMC_SP);
            }
        }

        // 流程环节处理
        Result httpResult = handleNodeName(ybjcyFlowVo, submitType, nowJob, ybid, opinion);
        if (!httpResult.isSuccess()){
            return httpResult;
        }else {
            if (submitType.equals(YbjcyFlowConstant.SUBMIT_TYPE_SUBMIT) && nowJob.getFhjmc().equals(YbjcyFlowConstant.HJMC_SH)){
                // 预备检查员晋升-组员
                this.promoteYbjcy(ybid,nowJob.getFhjmc());

            }else if (submitType.equals(YbjcyFlowConstant.SUBMIT_TYPE_SUBMIT) && nowJob.getFhjmc().equals(YbjcyFlowConstant.HJMC_SP)) {
                SpcyKpYbjcy ybjcy = spcyKpYbjcyService.getById(ybid);
                ybjcy.setFlczt(YbjcyFlowConstant.HJMC_LCJS);
                ybjcy.setFwcsj(new Date());
                spcyKpYbjcyService.updateById(ybjcy);
            }
        }
        return httpResult;

    }

    /**
     * 流程环节处理
     * */
    public Result handleNodeName(YbjcyFlowMapVo ybjcyFlowVo,String submitType, SpcySqsxJob job, String ybid, String opinion){
        HashMap<String, Object> map = ybjcyFlowVo.getMap();
        String dbrid = ybjcyFlowVo.getDbrid();// 下环节待办人
        String smgflag = ybjcyFlowVo.getSmgflag(); // 短信发送标志

        Result res = null;

        // 保存按钮
        if (submitType.equals(YbjcyFlowConstant.SUBMIT_TYPE_SAVE)){
            Result result = this.updateKpxx(ybid, map);
            if (!result.isSuccess()){
                return result;
            }
        }

        // 提交按钮
        if (submitType.equals(YbjcyFlowConstant.SUBMIT_TYPE_SUBMIT)){
            Result result = this.updateKpxx(ybid, map);
            if (!result.isSuccess()){
                return result;
            }

            // 流程任务id
            String jobId = "";
            if (job != null){
                jobId = job.getId();
            }

            // 跳转指定环节
            String nextNode = "";
            if (StringUtils.isNotBlank(ybjcyFlowVo.getNextNode())){
                nextNode = ybjcyFlowVo.getNextNode();
            }

            // 提交流程任务,待办人是否为空，指定待办人
            if (StringUtils.isBlank(dbrid)) {
                // 提交-流程任务
                res = this.passJob(ybid, jobId, opinion, nextNode, "");
            }else {
                // 提交-流程任务
                res = this.passJob(ybid, jobId, opinion, nextNode, dbrid);
            }
            if (!res.isSuccess()){
                return res;
            }else {
                SpcySqsxJob nowJob = (SpcySqsxJob)res.getResult();
                // 接收返回的流程任务，如果返回的流程任务id不相等，发送短信
                if (nowJob != null && !jobId.equals(nowJob.getId()) && StringUtils.isNotBlank(smgflag) && smgflag.equals("是")){
                    busService.sendSmsToPassJob(nowJob);
                }
            }
        }

        return Result.ok("提交成功");
    }

    /**
     * 验证预备检查员-参加了几次检查(满足两次-晋升组员)
     */
    public void promoteYbjcy(String ybid,String nodeName){
        SpcyKpYbjcy yb = spcyKpYbjcyService.getById(ybid);
        if (yb == null){
            log.error("预备检查员晋升组员失败，当前预备检查员信息不存在【{}】",ybid);
            return;
        }
        List<SpcyKpYbjcy> countYbjcy = spcyKpYbjcyService.list(new LambdaQueryWrapper<SpcyKpYbjcy>()
                .eq(StringUtils.isNotBlank(yb.getFuserid()),SpcyKpYbjcy::getFuserid, yb.getFuserid())
                .eq(StringUtils.isNotBlank(yb.getFjcyid()),SpcyKpYbjcy::getFjcyid,yb.getFjcyid()));
        if (countYbjcy.size() > 1){
            boolean isPromoting = true;
            for (SpcyKpYbjcy ybjcy : countYbjcy){
                // 是否存在不合格的
                if (StringUtils.isBlank(ybjcy.getFpj()) || ybjcy.getFpj().equals(SpcyConstant.YBJCY_PJ_BHG)){
                    isPromoting = false;
                    break;
                }
            }
            if (isPromoting) {
                SpcyRsHcy rsHcy = spcyRsHcyMapper.selectById(yb.getFjcyid());
                if (rsHcy != null) {
                    rsHcy.setFssk(SpcyConstant.HCY_SSK_ZYK);
                    spcyRsHcyMapper.updateById(rsHcy);

                    String logNr = "预备检查员晋升组员：【姓名】为[" + yb.getFjcyxm() + "];" +
                            "【所属库】从[预备检查员]设置为[" + SpcyConstant.HCY_SSK_ZYK + "]";
                    spcyLogService.addLogs(nodeName, logNr, ybid, LogConstant.LOGS_RS_HCY, SpcyConstant.LOGS_SYS_TYPE_BC);
                }
            }
        }
    }

    /**
     * 修改预备检查员基本信息
     * @param ybid
     * @param buffer
     * @return
     */
    public Result updateKpxx(String ybid,HashMap<String,Object> buffer){
        if (StringUtils.isBlank(ybid)){
            return Result.error("预备考评id不能存在");
        }
        SpcyKpYbjcy updateYbjcy = spcyKpYbjcyService.getById(ybid);
        if (updateYbjcy == null){
            return Result.error("当前年度考评信息不存在，请重试");
        }
        Map<String, Object> oldMap = ObjectToMapUtils.objectToMap(updateYbjcy);

        // 修改
        ConvertUtils.register(new DateConvert(), java.util.Date.class);
        try {
            BeanUtils.populate(updateYbjcy, buffer);
        }catch (IllegalAccessException e) {
            log.error("出错-保存预备考评【非法访问异常 ，llegalAccessException】,{}",e.getMessage());
        } catch (InvocationTargetException e) {
            log.error("出错-保存预备考评【调用TargetException，InvocationTargetException】,{}",e.getMessage());
        }
        spcyKpYbjcyService.updateById(updateYbjcy);

        String logContent = "基本信息修改: ";
        logContent += LogUtils.BeanModifyMsg(updateYbjcy,oldMap);
        spcyLogService.addLogs(LogConstant.LOGS_KP_YBJCY, logContent, ybid, LogConstant.LOGS_KP_YBJCY, SpcyConstant.LOGS_SYS_TYPE_XG);

        return Result.ok();
    }

    /**
     * 获取当前流程任务相关信息
     * @param jobid 流程任务id
     */
    public Map getJobConcernByJobId(String jobid){
        Map map = new HashMap();

        // 当前流转记录
        SpcySqsxJob job = spcySqsxJobService.getById(jobid);
        if (job == null){
            log.error("当前流程任务id为【{}】的流转记录不存在",jobid);
            return map;
        }
        String ybid = job.getFpid();
        if (org.apache.commons.lang3.StringUtils.isBlank(ybid)){
            log.error("当前流程任务id为【{}】的流转记录中的预备检查员考评id为空",jobid);
            return map;
        }

        // 预备信息
        SpcyKpYbjcy ndkpBasic = spcyKpYbjcyService.getById(ybid);

        // 流程任务流传记录
//        List<String> nodeList = Arrays.asList(NdkpConstant.NODENAME.split(",")); // 所有环节名称
        LambdaQueryWrapper<SpcySqsxJob> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(SpcySqsxJob::getFpid, ybid);
        queryWrapper.eq(SpcySqsxJob::getFlcmc,flowConstant.getFlowName());
        queryWrapper.orderByAsc(SpcySqsxJob::getFfssj);
        queryWrapper.orderByAsc(SpcySqsxJob::getCreateTime);
        List<SpcySqsxJob> jobList = spcySqsxJobService.list(queryWrapper);

        // 获取下环节待办人
        Map nextDbr = getNextDbr(ybid, jobid);
        String nextNode = nextDbr.get("nextNode").toString();
        List<AgentVo> dbrListByMap = busService.getDbrListByMap(nextDbr);

        map.put("ybkp",ndkpBasic); // 年度考评基本信息
        map.put("job",job); // 当前流转记录
        map.put("jobHistoryList",jobList); // 流程任务流传记录
        map.put("nextNodeDbrList",dbrListByMap); // 下环节待办人list
        map.put("nextNode",nextNode);

        return map;
    }

    /**
     * 获取下环节待办人
     * @param ybid 预备检查员id
     */
    public Map getNextDbr(String ybid,String jobid){
        String jobNodeName = busService.getJobNodeName(jobid); // 获取当前流程任务job环节

        // 下一个环节名称
        String nextNodeName = flowConstant.getNextNodeName(jobNodeName);
        Map nodeDbr = new HashMap();
        nodeDbr = getNodeDbr(ybid, nextNodeName, "");

        nodeDbr.put("nextNode",nextNodeName);

        return nodeDbr;
    }

    //初始化任务
    public Result initJob(String pid, CurrentUserVo currentUser){
        String nodeName = flowConstant.getFirstNode();
        //需要校验是否已经初始化过
        List<SpcySqsxJob> list = spcySqsxJobService.list(new LambdaQueryWrapper<SpcySqsxJob>()
                .eq(SpcySqsxJob::getFpid, pid)
                .eq(SpcySqsxJob::getFhjmc, nodeName)
                .eq(SpcySqsxJob::getFlcmc, flowConstant.getFlowName())
        );
        if(list.size()>0){
            log.error("预备检查员考评已经初始化了。申请事项id【{}】", pid);
            return Result.ok("操作成功");
        }
        Map nodeDbr = this.getNodeDbr(pid, nodeName, "");
        String nextNodeDbrIds = nodeDbr.get("dbrId").toString();
        return this.createNextJob(flowConstant,pid,null,currentUser,nodeName,nextNodeDbrIds);
    }

    /**
     * 提交当前环节的待办记录
     *  @param sqsxId 申请事项id
     *  @param jobId 当前环节id
     *  @param opinion 办理意见
     */
    public Result passJob(String sqsxId, String jobId, String opinion,String nextNodeName,String nextNodeDbrIds){
        //处理业务表的逻辑
        Result httpResult = this.passJob(flowConstant, sqsxId, jobId, opinion, nextNodeName, nextNodeDbrIds);
        return httpResult;
    }

    // 获取当前环节待办人
    public Map getNodeDbr(String pid, String nodeName, String dbrIds){
        Map map = new HashMap();
        String dbrId = "";
        String dbr = "";
        if(StringUtils.isNotBlank(dbrIds)){
            dbr = getDbrsByIds(dbrIds);
            dbrId = dbrIds;
        }else{
            // 待登记预备考评
            if (nodeName.equals(YbjcyFlowConstant.HJMC_DJ)){
                SpcyKpYbjcy yb = spcyKpYbjcyService.getById(pid);
                if (yb != null){
                    dbrId = yb.getFuserid();
                    dbr = yb.getFjcyxm();
                }
            }

            // 待审核预备考评
            if (nodeName.equals(YbjcyFlowConstant.HJMC_SH)){
                SpcyKpYbjcy yb = spcyKpYbjcyService.getById(pid);
                if (yb != null){
                    dbrId = yb.getFzzid();
                    dbr = yb.getFzzxm();
                }
                if (StringUtils.isBlank(dbrId)){
                    // 该环节待办人为空，跳转下环节
                    if (yb != null && StringUtils.isNotBlank(yb.getFsqsxid())) {
                        Map zbrBySqsxId = getZbrBySqsxId(yb.getFsqsxid());
                        dbrId = zbrBySqsxId.get("dbrId").toString();
                        dbr = zbrBySqsxId.get("dbr").toString();
                    }
                }
            }

            // 待审批预备考评
            if (nodeName.equals(YbjcyFlowConstant.HJMC_SP)){
                SpcyKpYbjcy yb = spcyKpYbjcyService.getById(pid);
                if (yb != null && StringUtils.isNotBlank(yb.getFsqsxid())) {
                    Map zbrBySqsxId = getZbrBySqsxId(yb.getFsqsxid());
                    dbrId = zbrBySqsxId.get("dbrId").toString();
                    dbr = zbrBySqsxId.get("dbr").toString();
                }
            }

        }

        map.put("dbrId",dbrId);
        map.put("dbr",dbr);
        return map;
    }

    // 获取当前环节待办人
    public Map getNodeDbr(String nodeName, String dbrIds){
        return this.getNodeDbr(null,nodeName,dbrIds);
    }

    // 根据待办人id，获取名称拼接起来
    private String getDbrsByIds(String dbrIds){
        //把待办人按id查出来  把名字拼起来
        String dbr = "";
        List<String> dbrIdsList = Arrays.asList(dbrIds.split(","));
        List<YcSysUser> sysUserList = new ArrayList<>();
        if (CollectionUtils.isNotEmpty(dbrIdsList)){
            sysUserList = ycSysUserService.listByIds(dbrIdsList);
        }

        if (CollectionUtils.isNotEmpty(sysUserList)){
            for (YcSysUser user : sysUserList){
                dbr += user.getRealname() + ",";
            }
        }

        return dbr;
    }

    // 获取主办人
    public Map getZbrBySqsxId(String sqsxId){
        Map map = new HashMap();
        String dbrId = "";
        String dbr = "";

        SpcySqsxBasic basic = spcySqsxBaiscService.getById(sqsxId);
        if (basic != null && StringUtils.isNotBlank(basic.getFzbr())){
            List<String> userids = Arrays.asList(basic.getFzbr().split(",|，"));
            if (CollectionUtils.isNotEmpty(userids)) {
                for (String uid : userids) {
                    YcSysUser sysUser = ycSysUserService.getById(uid);
                    if (sysUser != null) {
                        if (StringUtils.isBlank(dbrId)) {
                            dbrId += sysUser.getId();
                            dbr += sysUser.getRealname();
                        } else {
                            dbrId += "," + sysUser.getId();
                            dbr += "," + sysUser.getRealname();
                        }
                    }
                }
            }
        }

        map.put("dbrId",dbrId);
        map.put("dbr",dbr);
        return map;
    }

    // 退回流程
    public Result getReturnUpperFlowJob(String jobid,String opinion){
        if (StringUtils.isBlank(jobid)){
            return Result.error("当前流程任务id不能为空");
        }
        SpcySqsxJob job = spcySqsxJobService.getById(jobid);
        if (job == null){
            return Result.error("当前流程任务不存在");
        }
        // 办理状态 - 待办
        if (StringUtils.isNotBlank(job.getFblzt()) && (job.getFblzt().equals(SpcyConstant.BLZT_DB)
                || job.getFblzt().equals(SpcyConstant.BLZT_TH))){
            // 待办-获取上一个环节id
            String fsyhjid = job.getFsyhjid();
            SpcySqsxJob syhjJob = spcySqsxJobService.getById(fsyhjid);
            if (syhjJob != null){
                syhjJob.setFthyj(opinion);
                syhjJob.setFfssj(new Date());
                syhjJob.setFblzt(SpcyConstant.BLZT_TH);
                spcySqsxJobService.updateById(syhjJob);

                spcySqsxJobService.removeById(jobid); // 删除当前流程任务待办
            }
        }

        String logNr = "退回上一环节: ";
        Map<String, Object> map = ObjectToMapUtils.objectToMap(job);
        logNr += LogUtils.MapToStringMethod(map);
        spcyLogService.addLogs(job.getFhjmc(),logNr,job.getFpid(), LogConstant.LOGS_SQSX_JOB,SpcyConstant.LOGS_SYS_TYPE_TH);
        return Result.ok("success");
    }
}
